package xcmg.device.service.account;

import com.github.pagehelper.PageInfo;
import yb.ecp.fast.infra.util.PageHelperPlus;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.account.ArapDO;
import xcmg.device.dao.entity.account.ArapDetailDO;
import xcmg.device.dao.entity.account.CheckDO;
import xcmg.device.dao.entity.account.CheckDetailDO;
import xcmg.device.dao.entity.company.CompanyDealerDO;
import xcmg.device.dao.entity.company.CompanyInfoDO;
import xcmg.device.dao.entity.delivery.DeliveryNoteDO;
import xcmg.device.dao.entity.prepPay.PrepPayDO;
import xcmg.device.dao.entity.sale.SalesBillDO;
import xcmg.device.dao.entity.sale.SalesOutBillDO;
import xcmg.device.dao.entity.warehouse.WarehouseDeliveryDO;
import xcmg.device.dao.mapper.CompanyDealerMapper;
import xcmg.device.dao.mapper.CompanyInfoMapper;
import xcmg.device.dao.mapper.account.ArapDetailMapper;
import xcmg.device.dao.mapper.account.ArapMapper;
import xcmg.device.dao.mapper.account.CheckDetailMapper;
import xcmg.device.dao.mapper.account.CheckMapper;
import xcmg.device.dao.mapper.delivery.DeliveryNoteMapper;
import xcmg.device.dao.mapper.prepPay.PrepPayDOMapper;
import xcmg.device.dao.mapper.sale.SalesBillMapper;
import xcmg.device.dao.mapper.sale.SalesOutBillMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDeliveryMapper;
import xcmg.device.infra.CalcUtil;
import xcmg.device.infra.DateUtil;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.ExportUtil;
import xcmg.device.infra.enums.BillDesc;
import xcmg.device.infra.enums.PayTypeEnum;
import xcmg.device.infra.enums.SaleOutEnum;
import xcmg.device.service.GenDocumentService;
import xcmg.device.service.agent.ServiceStaffQuotaService;
import xcmg.device.service.company.DealerVehicleService;
import xcmg.device.service.vo.account.CheckAddVO;
import xcmg.device.service.vo.account.CheckDetailVO;
import xcmg.device.service.vo.account.CheckVO;
import xcmg.device.service.vo.agent.ServiceStaffQuotaUseVO;
import xcmg.device.service.vo.delivery.DeliveryNoteVO;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.util.ListUtil;
import yb.ecp.fast.infra.util.StringUtil;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class CheckService {

    @Autowired
    private FastGenClient fastGenClient;

    @Autowired
    private GenDocumentService genDocumentService;

    @Autowired
    private CheckMapper checkMapper;

    @Autowired
    private CheckDetailMapper checkDetailMapper;

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private ArapDetailMapper arapDetailMapper;

    @Autowired
    private ArapMapper arapMapper;

    @Autowired
    private DeliveryNoteMapper deliveryNoteMapper;

    @Autowired
    private WarehouseDeliveryMapper warehouseDeliveryMapper;

    @Autowired
    private CompanyDealerMapper companyDealerMapper;
    @Autowired
    private SalesOutBillMapper salesOutBillMapper;
    @Autowired
    private SalesBillMapper salesBillMapper;
    @Autowired
    private DealerVehicleService dealerVehicleService;
    @Autowired
    private PrepPayDOMapper prepPayDOMapper;
    @Autowired
    private ServiceStaffQuotaService serviceStaffQuotaService;
    @Autowired
    private CompanyInfoMapper companyInfoMapper;
    @Autowired
    private RefundCheckService refundCheckService;

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode add(CheckAddVO checkAddVO, String orgId, String userId) throws Exception {
        ActionResult<String> textResult = fastGenClient.textGuid();
        if (textResult.getCode() != ErrorCode.Success.getCode()) {
            return ErrorCode.IllegalArument;
        }
        CheckDetailDO detailDO = new CheckDetailDO();
        String billSingle = "";
        BigDecimal receiverPrice = BigDecimal.ZERO;
        String salesBillNo = null;
        for (CheckDetailVO detailVO : checkAddVO.getDetailList()) {
            receiverPrice = receiverPrice.add(detailVO.getCheckPrice());
            BeanUtils.copyProperties(detailVO, detailDO);
            ArapDetailDO arapDetailDO = arapDetailMapper.selectByPrimaryKey(detailDO.getArapDetailId());
            if (arapDetailDO == null) {
                throw new Exception("未找到应收单据详情，" + detailDO.getArapDetailId());
            }

            detailDO.setMainId(textResult.getValue());
            detailDO.setSaleBillType(arapDetailDO.getSaleBillType());
            boolean success = checkDetailMapper.insert(detailDO) > 0;
            if (!success) {
                throw new Exception("操作失败");
            }

            //更新应收详情记录
            arapDetailDO.setReceivePrice(arapDetailDO.getReceivePrice().add(detailDO.getCheckPrice()));
            if (arapDetailDO.getReceivePrice().compareTo(arapDetailDO.getTotalPrice()) > 0) {
                throw new Exception("应收金额不能大于单据总金额");
            }
            setRemainPriceAndIsSettle(arapDetailDO);
            success = arapDetailMapper.update(arapDetailDO) > 0;
            if (!success) {
                throw new Exception("更新应收记录失败");
            }

            //更新单据结算状态
            billSingle = arapDetailDO.getBillSingle();
            if (BillDesc.DeliveryNo.getDesc().equals(arapDetailDO.getBillSingle())) {//发货通知单
                DeliveryNoteDO deliveryNoteDO = deliveryNoteMapper.item(detailVO.getBillId());
                if (deliveryNoteDO == null) {
                    throw new Exception("未找到发货通知单");
                }
                if (arapDetailDO.getIsSettle() == 1) {
                    deliveryNoteDO.setCheckState(2);
                } else {
                    deliveryNoteDO.setCheckState(1);
                }
                if (StringUtil.isNullOrEmpty(deliveryNoteDO.getOutLocation())) {
                    //代理商结算时
                    deliveryNoteDO.setOutLocation(checkAddVO.getHeaderInfo().getOutLocation());
                    deliveryNoteDO.setOutArea(checkAddVO.getHeaderInfo().getOutArea());
                    deliveryNoteDO.setSapOutArea(checkAddVO.getHeaderInfo().getSapOutArea());

                    WarehouseDeliveryDO warehouseDeliveryDO = warehouseDeliveryMapper.findByBusinessOrder(deliveryNoteDO.getDeliveryNo(), deliveryNoteDO.getSupplierOrgId());
                    if (warehouseDeliveryDO == null) {
                        throw new Exception("未找到出库事物单");
                    }
                    warehouseDeliveryDO.setWarehouseCode(deliveryNoteDO.getOutLocation());
                    warehouseDeliveryDO.setOutArea(deliveryNoteDO.getOutArea());
                    warehouseDeliveryDO.setSapOutArea(deliveryNoteDO.getSapOutArea());
                    warehouseDeliveryMapper.updateByPrimaryKey(warehouseDeliveryDO);
                }
                deliveryNoteMapper.update(deliveryNoteDO);
            }

            if (BillDesc.SalesOutNo.getDesc().equals(arapDetailDO.getBillSingle())) {//销售出库单
                SalesOutBillDO salesOutBillDO = salesOutBillMapper.selectByPrimaryKey(detailVO.getBillId());
                if (salesOutBillDO == null) {
                    throw new Exception("未找到销售出库单");
                }
                salesBillNo = salesOutBillDO.getSalesBillNo();
                if (arapDetailDO.getIsSettle() == 1) {
                    salesOutBillDO.setCheckState((short) 2);
                } else {
                    salesOutBillDO.setCheckState((short) 1);
                }
                success = salesOutBillMapper.updateByPrimaryKeySelective(salesOutBillDO) > 0;
                if (!success) {
                    throw new Exception("更新销售出库单失败");
                }
                // 扣减服务人员待回款额度
                subtractAmountToBeRefunded(detailDO, salesOutBillDO, true);
            }
        }

        CheckDO checkDO = addCheckInfo(checkAddVO, textResult, billSingle);
        ArapDO arapDO = arapMapper.selectByAccOrgId(checkDO.getSupplierOrgId(), checkDO.getPurchaseOrgId(), 0);
        if (arapDO == null) {
            throw new Exception("未找到应收记录");
        }
        //更新车辆信息
        updateUseVehicleQuota(checkAddVO, orgId, billSingle, salesBillNo);
        //更新应收款信息
        updatePayPrice(orgId, userId, checkDO, arapDO, checkAddVO.getHeaderInfo());
        //更新应收主记录
        ArapDO updateArapDO = new ArapDO();
        updateArapDO.setOldReceiverPrice(arapDO.getReceiverPrice());
        updateArapDO.setReceiverPrice(arapDO.getReceiverPrice().subtract(receiverPrice));
        updateArapDO.setUpdateDate(new Date());
        updateArapDO.setId(arapDO.getId());
        boolean success = arapMapper.updateSelective(updateArapDO) > 0;
        if (!success) {
            throw new Exception("更新应收记录失败");
        }

        if (BillDesc.DeliveryNo.getDesc().equals(billSingle)) {
            //更新客户额度
            CompanyDealerDO dealerDO = companyDealerMapper.itemByOrgId(checkDO.getSupplierOrgId(), checkDO.getPurchaseOrgId());
            if (dealerDO == null) {
                throw new Exception("客户不存在");
            }
            if (dealerDO.getEnableLimit() == 1) {
                dealerDO.setUsedLimit(dealerDO.getUsedLimit().subtract(checkDO.getTotalPrice()));
                success = companyDealerMapper.update(dealerDO) > 0;
                if (!success) {
                    throw new Exception("更新客户额度失败");
                }
            }
        }
        return ErrorCode.Success;
    }

    //扣减服务人员待收款金额
    private void subtractAmountToBeRefunded(CheckDetailDO detailDO, SalesOutBillDO salesOutBillDO, boolean isSettleAccounts) throws Exception {
        String borrowBillNo = salesOutBillDO.getBorrowBillNo();
        if (StringUtils.isBlank(borrowBillNo)) {
            return;
        }

        String salesBillNo = salesOutBillDO.getSalesBillNo();
        if (StringUtils.isBlank(salesBillNo)){
            return;
        }
        //获取服务人员ID
        SalesBillDO salesBillDO = salesBillMapper.selectBySalesBillNo(salesBillNo);
        String servicePersonId = salesBillDO.getServicePersonId();
        Integer countIsDisable = serviceStaffQuotaService.countIsDisable(servicePersonId);
        if (countIsDisable <= 0) {
            return;
        }
        ServiceStaffQuotaUseVO serviceStaffQuotaUseVO = new ServiceStaffQuotaUseVO();
        serviceStaffQuotaUseVO.setStaffName(salesOutBillDO.getServicePersonName());
        serviceStaffQuotaUseVO.setStaffId(servicePersonId);
        if (isSettleAccounts) {
            serviceStaffQuotaUseVO.setPendingPayment(CalcUtil.subtract(BigDecimal.ZERO, detailDO.getCheckPrice()));
        } else {
            serviceStaffQuotaUseVO.setPendingPayment(detailDO.getCheckPrice());
        }
        ErrorCode errorCode = serviceStaffQuotaService.useQuotaSubtract(serviceStaffQuotaUseVO);
        if (ErrorCode.Success != errorCode) {
            throw new Exception("服务人员代收回款额度失败");
        }
    }

    //更新车辆额度，预付款金额
    private void updateUseVehicleQuota(CheckAddVO checkAddVO, String orgId, String billSingle, String salesBillNo) throws Exception {
        if (!BillDesc.SalesOutNo.getDesc().equals(billSingle)) {
            return;
        }
        //更新销售单相关信息
        CheckVO checkVO = checkAddVO.getHeaderInfo();
        BigDecimal useVehicleQuota = checkVO.getUseVehicleQuota();
        if (null == useVehicleQuota || useVehicleQuota.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }
        //销售出库单更新客户车辆使用额度
        SalesBillDO salesBillDO = salesBillMapper.selectBySalesBillNo(salesBillNo);
        if (null == salesBillDO) {
            throw new Exception("销售单信息不存在");
        }
        ErrorCode errorCode = dealerVehicleService.updateQuota(salesBillDO, useVehicleQuota, orgId);
        if (ErrorCode.Success != errorCode) {
            throw new Exception("客户车辆额度扣减失败");
        }
    }

    private void updatePayPrice(String orgId, String userId, CheckDO checkDO, ArapDO arapDO, CheckVO checkVO) throws Exception {
        // 2019-12-03 主机厂也调整
        /*CompanyInfoDO companyInfoDO = companyInfoMapper.item(orgId);
        if (null == companyInfoDO || null == companyInfoDO.getIsSap() || 0 != companyInfoDO.getIsSap()) {
            return;
        }*/

        BigDecimal advancePayPrice = checkVO.getAdvancePayPrice();
        if (null == advancePayPrice || advancePayPrice.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }//预付款详情添加预付款信息
        ArapDO updateArapDO = new ArapDO();
        updateArapDO.setOldPrepPayPrice(arapDO.getPrepPayPrice());
        updateArapDO.setPrepPayPrice(arapDO.getPrepPayPrice().subtract(advancePayPrice));
        updateArapDO.setUpdateDate(new Date());
        updateArapDO.setId(arapDO.getId());
        boolean success = arapMapper.updateSelective(updateArapDO) > 0;
        if (!success) {
            throw new Exception("更新应收记录失败");
        }

        String checkOrder = checkDO.getCheckOrder();
        PrepPayDO prepPayDO = new PrepPayDO();
        prepPayDO.setId(fastGenClient.textGuid().getValue());
        prepPayDO.setBillType(1);
        CompanyDealerDO dealerDO = companyDealerMapper.itemByOrgId(checkDO.getSupplierOrgId(), checkDO.getPurchaseOrgId());
        if (null != dealerDO) {
            prepPayDO.setCustomerName(dealerDO.getCompanyName());
            prepPayDO.setCustomerId(String.valueOf(dealerDO.getId() == null ? "0" : dealerDO.getId()));
        }
        prepPayDO.setTotalAmount(updateArapDO.getPrepPayPrice());
        prepPayDO.setTransactionAmount(CalcUtil.subtract(BigDecimal.ZERO, advancePayPrice));
        prepPayDO.setCreateId(userId);
        prepPayDO.setOrgId(orgId);
        prepPayDO.setDiscardFlag(0);
        prepPayDO.setCreateDate(new Date());
        prepPayDO.setBillNo(checkOrder);
        int count = prepPayDOMapper.insertSelective(prepPayDO);
        if (count <= 0) {
            throw new Exception("新增预付款信息失败");
        }
    }

    private CheckDO addCheckInfo(CheckAddVO checkAddVO, ActionResult<String> textResult, String billSingle) throws Exception {
        CheckDO checkDO = new CheckDO();
        BeanUtils.copyProperties(checkAddVO.getHeaderInfo(), checkDO);
        checkDO.setId(textResult.getValue());
        checkDO.setCheckOrder(genDocumentService.getDocumentNo(BillDesc.FDCheck));
        setRealPrice(billSingle, checkDO);
        checkDO.setCreateDate(new Date());
        checkDO.setPayDesc(PayTypeEnum.getDescByType(checkAddVO.getHeaderInfo().getPayType()));
        CompanyDealerDO dealerDO = companyDealerMapper.itemByOrgId(checkDO.getSupplierOrgId(), checkDO.getPurchaseOrgId());
        if (null != dealerDO) {

        }
        boolean success = checkMapper.insert(checkDO) > 0;
        if (!success) {
            throw new Exception("新增收付款记录失败");
        }
        return checkDO;
    }

    private void setRemainPriceAndIsSettle(ArapDetailDO arapDetailDO) {
        if (BillDesc.SalesOutNo.getDesc().equals(arapDetailDO.getBillSingle()) && null != arapDetailDO.getSaleBillType()
                && SaleOutEnum.SaleBillTypeThreePack.getCode() == arapDetailDO.getSaleBillType()) {//销售订单，且三包
            arapDetailDO.setIsSettle(1);
            return;
        }
        arapDetailDO.setRemainPrice(arapDetailDO.getTotalPrice().subtract(arapDetailDO.getReceivePrice()));
        if (arapDetailDO.getRemainPrice().compareTo(BigDecimal.ZERO) == 0) {
            arapDetailDO.setIsSettle(1);
        }
    }

    private void setRealPrice(String billSingle, CheckDO checkDO) {
        if (!BillDesc.DeliveryNo.getDesc().equals(billSingle)) {
            return;
        }
        checkDO.setRealPrice(checkDO.getTotalPrice().subtract(checkDO.getDiscountPrice()));
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode reverse(String id, String orgId, String userId) throws Exception {
        CheckDO checkDO = checkMapper.selectByPrimaryKey(id);
        if (checkDO == null) {
            return ErrorCode.IllegalArument;
        }

        if (StringUtils.isNotBlank(checkDO.getRefundOrderId())) {//红冲退货单收款信息
            return refundCheckService.reverse(checkDO.getRefundOrderId(),orgId,userId);
        }

        List<CheckDetailDO> listDO = checkDetailMapper.list(id);
        if (ListUtil.isNullOrEmpty(listDO)) {
            return ErrorCode.IllegalArument;
        }
        checkDO.setIsReverse(1);
        boolean success = checkMapper.update(checkDO) > 0;
        if (!success) {
            throw new Exception("更新失败");
        }

        String billType = "";
        BigDecimal receiverPrice = BigDecimal.ZERO;
        String salesBillNo = null;
        for (CheckDetailDO detailDO : listDO) {
            receiverPrice = receiverPrice.add(detailDO.getCheckPrice());
            //更新应收详情记录
            ArapDetailDO arapDetailDO = arapDetailMapper.selectByPrimaryKey(detailDO.getArapDetailId());
            if (arapDetailDO == null) {
                throw new Exception("未找到应收单据详情，" + detailDO.getArapDetailId());
            }
            arapDetailDO.setReceivePrice(arapDetailDO.getReceivePrice().subtract(detailDO.getCheckPrice()));
            arapDetailDO.setRemainPrice(arapDetailDO.getTotalPrice().subtract(arapDetailDO.getReceivePrice()));
            if (arapDetailDO.getRemainPrice().compareTo(BigDecimal.ZERO) > 0) {
                arapDetailDO.setIsSettle(0);
            }
            Integer saleBillType = arapDetailDO.getSaleBillType();
            if (null != saleBillType && SaleOutEnum.SaleBillTypeThreePack.getCode() == saleBillType) {//销售出库单，三包
                arapDetailDO.setRemainPrice(BigDecimal.ZERO);
                arapDetailDO.setIsSettle(0);
            }
            success = arapDetailMapper.update(arapDetailDO) > 0;
            if (!success) {
                throw new Exception("更新应收记录失败");
            }
            billType = arapDetailDO.getBillSingle();
            //更新发货通知单结算状态
            if (BillDesc.DeliveryNo.getDesc().equals(arapDetailDO.getBillSingle())) {
                DeliveryNoteDO deliveryNoteDO = deliveryNoteMapper.item(detailDO.getBillId());
                if (deliveryNoteDO == null) {
                    throw new Exception("未找到发货通知单");
                }
                if (arapDetailDO.getReceivePrice().compareTo(BigDecimal.ZERO) == 0) {
                    deliveryNoteDO.setCheckState(0);
                } else {
                    deliveryNoteDO.setCheckState(1);
                }
                deliveryNoteMapper.update(deliveryNoteDO);
            }

            if (BillDesc.SalesOutNo.getDesc().equals(arapDetailDO.getBillSingle())) {
                SalesOutBillDO salesOutBillDO = salesOutBillMapper.selectByPrimaryKey(detailDO.getBillId());
                if (salesOutBillDO == null) {
                    throw new Exception("未找到销售出库单");
                }
                salesBillNo = salesOutBillDO.getSalesBillNo();
                if (arapDetailDO.getReceivePrice().compareTo(BigDecimal.ZERO) == 0) {
                    salesOutBillDO.setCheckState((short) 0);
                } else {
                    salesOutBillDO.setCheckState((short) 1);
                }
                salesOutBillMapper.updateByPrimaryKeySelective(salesOutBillDO);
                // 反更服务人员未回款金额
                subtractAmountToBeRefunded(detailDO, salesOutBillDO, false);
            }
        }
        //更新应收主记录
        ArapDO arapDO = arapMapper.selectByAccOrgId(checkDO.getSupplierOrgId(), checkDO.getPurchaseOrgId(), 0);
        if (arapDO == null) {
            throw new Exception("未找到应收记录");
        }
        arapDO.setOldReceiverPrice(arapDO.getReceiverPrice());
        arapDO.setReceiverPrice(arapDO.getReceiverPrice().add(receiverPrice));
        arapDO.setUpdateDate(new Date());
        success = arapMapper.updateSelective(arapDO) > 0;
        if (!success) {
            throw new Exception("更新应收记录失败");
        }
        //回退车辆额度，回退预收款金额
        reverseSalesOutInfo(orgId, checkDO, billType, salesBillNo, arapDO, userId);
        reversePayPrice(orgId, checkDO, arapDO, userId);
        return ErrorCode.Success;
    }

    private void reverseSalesOutInfo(String orgId, CheckDO checkDO, String billType, String salesBillNo, ArapDO arapDO, String userId) throws Exception {
        if (!BillDesc.SalesOutNo.getDesc().equals(billType)) {
            return;
        }
        //更新销售单相关信息
        BigDecimal useVehicleQuota = checkDO.getUseVehicleQuota();
        if (null == useVehicleQuota || useVehicleQuota.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }
        //销售出库单更新客户车辆使用额度
        SalesBillDO salesBillDO = salesBillMapper.selectBySalesBillNo(salesBillNo);
        if (null == salesBillDO) {
            throw new Exception("销售单信息不存在");
        }
        ErrorCode errorCode = dealerVehicleService.updateQuota(salesBillDO, CalcUtil.subtract(BigDecimal.ZERO, useVehicleQuota), orgId);
        if (ErrorCode.Success != errorCode) {
            throw new Exception("客户车辆额度扣减失败");
        }

    }

    //红冲预付款
    private void reversePayPrice(String orgId, CheckDO checkDO, ArapDO arapDO, String userId) throws Exception {
        CompanyInfoDO companyInfoDO = companyInfoMapper.item(orgId);
        if (null == companyInfoDO || null == companyInfoDO.getIsSap() || 0 != companyInfoDO.getIsSap()) {
            return;
        }

        BigDecimal advancePayPrice = checkDO.getAdvancePayPrice();
        if (null == advancePayPrice || advancePayPrice.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }
        //作废预付款记录
        obsoleteAdvancePayment(orgId, checkDO, userId);
        //回退预付款金额
        ArapDO updateArapDO = new ArapDO();
        updateArapDO.setOldPrepPayPrice(arapDO.getPrepPayPrice());
        updateArapDO.setPrepPayPrice(arapDO.getPrepPayPrice().add(advancePayPrice));
        updateArapDO.setUpdateDate(new Date());
        updateArapDO.setId(arapDO.getId());
        boolean success = arapMapper.updateSelective(updateArapDO) > 0;
        if (!success) {
            throw new Exception("更新应收记录预付款失败");
        }

    }

    //作废预付款记录
    private void obsoleteAdvancePayment(String orgId, CheckDO checkDO, String userId) throws Exception {
        String checkOrder = checkDO.getCheckOrder();
        PrepPayDO record = new PrepPayDO();
        record.setDiscardFlag(1);
        record.setDiscardDate(new Date());
        record.setDiscardPersonId(userId);
        record.setBillNo(checkOrder);
        record.setOrgId(orgId);
        int updateCount = prepPayDOMapper.updateByBillNo(record);
        if (updateCount <= 0) {
            throw new Exception("更新预付款记录失败");
        }
    }

    public CheckAddVO item(String id) {
        CheckAddVO result = new CheckAddVO();
        CheckDO checkDO = checkMapper.selectByPrimaryKey(id);
        if (checkDO == null) {
            return result;
        }
        CheckVO checkVO = new CheckVO();
        BeanUtils.copyProperties(checkDO, checkVO);
        result.setHeaderInfo(checkVO);
        List<CheckDetailVO> listVO = new ArrayList<>();
        List<CheckDetailDO> listDO = checkDetailMapper.list(id);
        //相关的发货通知单id
        Set<String> billIds = new HashSet<>();
        for (CheckDetailDO entity : listDO) {
            billIds.add(entity.getBillId());
            CheckDetailVO model = new CheckDetailVO();
            BeanUtils.copyProperties(entity, model);
            listVO.add(model);
        }
        List<String> sapOutNoList = getsapOutNoListByIds(billIds);
        checkVO.setSapOutNoList(sapOutNoList);
        result.setDetailList(listVO);
        return result;
    }

    private List<String> getsapOutNoListByIds(Set<String> billIds) {
        if (CollectionUtils.isEmpty(billIds)) {
            return Collections.emptyList();
        }
        List<String> result = new ArrayList<>(billIds.size());
        //根据发货通知单id 查询
        DeliveryNoteVO deliveryNoteVo = new DeliveryNoteVO();
        deliveryNoteVo.setIds(new ArrayList<String>(billIds));
        List<DeliveryNoteDO> ll = deliveryNoteMapper.list(deliveryNoteVo);
        if (CollectionUtils.isNotEmpty(ll)) {
            for (DeliveryNoteDO ddo : ll) {
                if (null != ddo.getSapOutNo() && !result.contains(ddo.getSapOutNo())) {
                    result.add(ddo.getSapOutNo());
                }
            }
        }
        return result;
    }

    public PageCommonVO list(SearchCommonVO<CheckVO> condition) {
        PageCommonVO result = new PageCommonVO();
        PageHelperPlus.orderBy("create_date desc");
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<CheckDO> doList = checkMapper.list(condition.getFilters());
        List<CheckVO> voList = new ArrayList<>();
        for (CheckDO entity : doList) {
            CheckVO model = new CheckVO();
            BeanUtils.copyProperties(entity, model);
            voList.add(model);
        }
        result.setPageInfo(new PageInfo(doList));
        result.setPageInfoList(voList);
        return result;
    }

    public void export(List<String> ids) throws Exception {
        PageHelperPlus.orderBy("create_date desc");
        invokeExport(checkMapper.findByIds(ids));
    }

    public void exportAll(CheckVO condition) throws Exception {
        Integer count = checkMapper.listCount(condition);
        List<CheckDO> dataList = new ArrayList<>();
        int times = count / 500 + 1;
        for (int i = 0; i < times; i++) {
            PageHelperPlus.startPage(i + 1, 500, "create_date desc");
            dataList.addAll(checkMapper.list(condition));
        }
        invokeExport(dataList);
    }

    private void invokeExport(List<CheckDO> doList) throws Exception {
        String title = "收款单数据导出";
        String[] rowsName = new String[]{"序号", "收款单号", "客户名称", "结算方式", "收款金额", "优惠金额",
                "实际收款金额", "经办人", "收款时间", "是否红冲"};
        List<Object[]> dataList = new ArrayList<>();
        Object[] objs;
        for (int i = 0; i < doList.size(); i++) {
            CheckDO exportDO = doList.get(i);
            objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = exportDO.getCheckOrder();
            objs[2] = exportDO.getPurchaseOrgName();
            objs[3] = exportDO.getSettleType() == 0 ? "按订单结算" : "按金额结算";
            objs[4] = exportDO.getTotalPrice();
            objs[5] = exportDO.getDiscountPrice();
            objs[6] = exportDO.getRealPrice();
            objs[7] = exportDO.getOperatorName();
            objs[8] = DateUtil.formatDateTime(exportDO.getCreateDate());
            objs[9] = exportDO.getIsReverse() == 0 ? "否" : "是";
            dataList.add(objs);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    /**
     * 审核
     *
     * @param id
     * @param pass true通过，false 返回
     * @return
     */
    public ErrorCode audit(String id, boolean pass) {
        CheckDO checkDO = checkMapper.selectByPrimaryKey(id);
        if (null == checkDO) {
            return ErrorCode.AbnormalDetailArgumentError;
        }
        if (pass) {
            checkDO.setAuditStatus(1);
        } else {
            checkDO.setAuditStatus(0);
        }
        checkMapper.update(checkDO);
        return ErrorCode.Success;
    }
}
